<template>
<div class="sql-edit" :class="sqlFllScreen?'sqlFllScreen':''">
    <div class="sql-edit-tool">
        <div class="btns" v-for="(item, i) in btnList" :key="i" @click="handleClick(item.method)">
            <i :class="`iconfont ${item.icon}`"></i>
            <span>{{item.name}}</span>
        </div>
    </div>
    <div id="container" ref="container"></div>
</div>
</template>

<script>
import * as monaco from 'monaco-editor'
import sqlFormatter from 'sql-formatter'
import { language } from 'monaco-editor/esm/vs/basic-languages/sql/sql'
let { keywords, builtinFunctions, operators } = language
let { languages: { CompletionItemKind: { Text, Function, Method }, CompletionItemInsertTextRule: { InsertAsSnippet } }, editor } = monaco

export default {
    name: 'SqlEdit',
    props: {
        data: {
            type: String
        },
        tableMetaData: {
            type: Object
        }
    },
    data () {
        return {
            sqlFllScreen: false,
            editor: null,
            btnList: [{
                    icon: 'icon-baocun',
                    name: '保存',
                    method: 'save'
                },
                {
                    icon: 'icon-formatpainter',
                    name: '格式化',
                    method: 'handleFormat'
                },
                {
                    icon: 'icon-quanping1',
                    name: '全屏',
                    method: 'handleFullScreen'
                }
            ],
            caretOffset: null,
            editorValue: null,
            currentSql: null,
            currentKey: null,
            allColumns: {
                t1: ['id', 'name1', 'type1', 'content1', 'create_time1', 'create_user1'],
                t2: ['id', 'name2', 'type2', 'content2', 'create_time2', 'create_user2'],
                t3: ['id', 'name3', 'type3', 'content3', 'create_time3', 'create_user3']
            },
            allTables: ['t1', 't2', 't3'],
            hints: {
                suggestions: []
            }
        }
    },
    methods: {
        initKeyHints () {
            let keyHints = []
            for (let i = 0; i < keywords.length; i++) {
                keyHints.push({
                    label: keywords[i],
                    kind: Text, // 这里Function也可以是别的值，主要用来显示不同的图标
                    insertText: `${keywords[i]} `, // 此项没有的话，默认是label值
                    insertTextRules: InsertAsSnippet
                })
            }
            for (let i = 0; i < builtinFunctions.length; i++) {
                keyHints.push({
                    label: builtinFunctions[i],
                    kind: Function, // 这里Function也可以是别的值，主要用来显示不同的图标
                    // eslint-disable-next-line
                    insertText: builtinFunctions[i] + '(${1:condition})', // 此项没有的话，默认是label值
                    insertTextRules: InsertAsSnippet
                })
            }
            for (let i = 0; i < operators.length; i++) {
                keyHints.push({
                    label: operators[i],
                    kind: Method, // 这里Function也可以是别的值，主要用来显示不同的图标
                    insertText: `${operators[i]} `, // 此项没有的话，默认是label值
                    insertTextRules: InsertAsSnippet
                })
            }
            return keyHints
        },
        getHints () {
            let result = []
            let currentId = `t${Math.floor(Math.random() * 3) + 1}`
            let arr = this.allColumns[currentId]
            for (let i = 0; i < arr.length; i++) {
                result.push({
                    label: arr[i],
                    kind: Text, // 这里Function也可以是别的值，主要用来显示不同的图标
                    insertText: `${arr[i]} `, // 此项没有的话，默认是label值
                    insertTextRules: InsertAsSnippet
                })
            }
            result.push({
                label: new Date().getTime().toString(),
                kind: Text, // 这里Function也可以是别的值，主要用来显示不同的图标
                insertText: new Date().getTime().toString(), // 此项没有的话，默认是label值
                insertTextRules: InsertAsSnippet
            })
            this.hints.suggestions = this.initKeyHints().concat(result)
        },
        initEditor () {
            let self = this
            self.editor = editor.create(self.$refs.container, {
                value: this.data,
                language: 'sql',
                minimap: {
                    enabled: false
                }
            })
            // 提示项设值
            monaco.languages.registerCompletionItemProvider('sql', {
                provideCompletionItems: (model, position, context, USER_TOKEN) => {
                    self.getHints()
                    return self.hints
                }
            })
        },
        handleClick (method) {
            this[method]()
        },
        save () {
            this.$emit('save', this.editor.getValue())
        },
        handleFullScreen () {
            this.sqlFllScreen = !this.sqlFllScreen
            this.$nextTick(() => {
                this.editor.layout()
            })
        },
        handleFormat () {
            let selection = this.editor.getSelection()
            let selectionText = this.editor.getModel().getValueInRange(selection)
            if (selectionText) {
                let r = {
                    identifier: {
                        major: 1,
                        minor: 1
                    },
                    range: selection,
                    text: sqlFormatter.format(selectionText, {
                        language: 'db2',
                        indent: '  '
                    }),
                    forceMoveMarkers: false
                }
                this.editor.executeEdits('my-source', [r])
            } else {
                this.$message.error('请选择代码片段')
            }
        }
    },
    mounted () {
        this.initEditor()
    }
}
</script>

<style lang="less" scoped>
.sql-edit {
    background-color: #ffffff;
    z-index: 2;
    width: 100%;
    border-radius: 4px;
    overflow: hidden;
}

.sql-edit-tool {
    width: 100%;
    background-color: #fff;
    display: flex;
    height: 32px;
    align-items: center;

    .btns {
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-left: 10px;

        span {
            font-size: 12px;
        }

        i {
            font-size: 20px;
            padding-right: 3px;
        }
        &:hover {
            i, span {
                color: #2680eb;
            }
        }
    }
}

#container {
    height: 300px;
}

.sqlFllScreen {
    position: fixed;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 2003;

    #container {
        height: calc(100% - 32px);
    }
}
</style>
